package org.moonlight.push.server.xiaomi;

import com.xiaomi.xmpush.server.Constants;
import com.xiaomi.xmpush.server.Message;
import com.xiaomi.xmpush.server.Result;
import com.xiaomi.xmpush.server.Sender;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.moonlight.push.server.xiaomi.req.XiaomiMessage;

import java.util.*;

/**
 * 小米开发文档 - https://dev.mi.com/console/doc/detail?pId=2775
 *              https://dev.mi.com/console/doc/detail?pId=1278#_2_1
 * @author Moonlight
 * @date 2022-10-31 9:47
 */
@Slf4j
public class XiaoMiClient {
    private final static String APP_ID = "";
    private final static String APP_KEY = "";
    private final static String APP_SECRET = "";
    private final static String APP_PACKAGE_NAME = "";

    private boolean init = false;

    private final static XiaoMiClient client = new XiaoMiClient();

    public static XiaoMiClient getInstance() {
        return client;
    }

    private XiaoMiClient() {
        if (!init()) {
            throw new RuntimeException("XiaoMiClient初始化失败");
        }
    }

    private boolean init() {
        if (init) {
            return true;
        }
        if (StringUtils.isBlank(APP_ID)) {
            log.error("[XiaoMiClient init] XiaoMiClient初始化失败. xiaomi app id 不应该为空");
            return false;
        }
        if (StringUtils.isBlank(APP_KEY)) {
            log.error("[XiaoMiClient init] XiaoMiClient初始化失败. xiaomi app key 不应该为空");
            return false;
        }
        if (StringUtils.isBlank(APP_SECRET)) {
            log.error("[XiaoMiClient init] XiaoMiClient初始化失败. xiaomi app secret 不应该为空");
            return false;
        }
        if (StringUtils.isBlank(APP_PACKAGE_NAME)) {
            log.error("[XiaoMiClient init] XiaoMiClient初始化失败. xiaomi app package name 不应该为空");
            return false;
        }

        this.init = true;
        return this.init;
    }

    /**
     * 功能描述:
     *   发送消息到指定设备上
     *   regId是app在客户端向小米推送服务注册时, 小米推送服务端根据设备标识和appId以及当前时间戳生成,
     *   因此能够保证每个设备上每个app对应的regId都是不同的, 可以作为每台设备上app的唯一标识；
     *   注: 需要开发者自己的服务器接收客户端返回的regid并存储在自身服务器；
     * @param message {@link XiaomiMessage}
     * @param retries 失败后重试的次数
     * @return result {@link Result}
     * @author moonlight<bzeng@ibingli.com>
     * @date 2022/10/31 10:35
     **/
    public Result sendMessageToRegId(XiaomiMessage message, int retries) throws Exception {
        // 小米官方规定 - 正式环境下使用Push服务，启动时需要调用如下代码
        Constants.useOfficial();

        Sender sender = new Sender(APP_SECRET);
        Message msg = message.buildXiaoMiMsg(APP_PACKAGE_NAME);
        Result result = sender.send(msg, message.getReceiverId(), retries);

        log.info("[XiaoMiClient sendMessageToRegId] XiaomiMessage[{}] Message[{}] result[{}]", message, msg, result);

        return result;
    }

    /**
     * 功能描述:
     *   发送消息到指定设备上
     *   regId是app在客户端向小米推送服务注册时, 小米推送服务端根据设备标识和appId以及当前时间戳生成,
     *   因此能够保证每个设备上每个app对应的regId都是不同的, 可以作为每台设备上app的唯一标识；
     *   注: 需要开发者自己的服务器接收客户端返回的regid并存储在自身服务器；
     * @param message {@link XiaomiMessage}
     * @param regIdList 小米推送服务注册ID
     * @param retries 失败后重试的次数
     * @return result {@link Result}
     * @author moonlight<bzeng@ibingli.com>
     * @date 2022/10/31 10:35
     **/
    public Result sendMessageToRegIds(XiaomiMessage message, List<String> regIdList, int retries) throws Exception {
        // 小米官方规定 - 正式环境下使用Push服务，启动时需要调用如下代码
        Constants.useOfficial();

        Sender sender = new Sender(APP_SECRET);
        Message msg = message.buildXiaoMiMsg(APP_PACKAGE_NAME);
        Result result = sender.send(msg, regIdList, retries);

        log.info("[XiaoMiClient sendMessageToRegIds] XiaomiMessage[{}] Message[{}] result[{}]", message, msg, result);

        return result;
    }

    /**
     * 功能描述:
     *   发送主题消息
     *   Topic消息, 开发者如果想要给不同的用户群体（量级一般比较大）发送不同的推送消息,
     *   比如不同的客户端版本、 不同地域、男女等的用户群体，那么使用Topic消息就非常适合；
     *   通过给不同的用户群体打不同的标签（topic）来实现, 我们内部还为全量用户打了统一标签, 开发者可以直接使用全量标签发送, 方便快捷；
     *   开发者还可以使用topic做交并差集运算，以达到更精细推送的目的；
     *   订阅标签 - https://dev.mi.com/console/doc/detail?pId=1278#_6
     * @param message {@link XiaomiMessage}
     * @param topic 主题
     * @param retries 失败后重试的次数
     * @return result {@link Result}
     * @author moonlight<bzeng@ibingli.com>
     * @date 2022/10/31 10:35
     **/
    public Result sendMessageToTopic(XiaomiMessage message, String topic, int retries) throws Exception {
        // 小米官方规定 - 正式环境下使用Push服务，启动时需要调用如下代码
        Constants.useOfficial();

        Sender sender = new Sender(APP_SECRET);
        Message msg = message.buildXiaoMiMsg(APP_PACKAGE_NAME);
        Result result = sender.broadcast(msg, topic, retries);

        log.info("[XiaoMiClient sendMessageToTopic] XiaomiMessage[{}] Message[{}] result[{}]", message, msg, result);

        return result;
    }

    public static void main(String[] args) throws Exception {
        XiaomiMessage msg = new XiaomiMessage();

        msg.setReceiverId("");
        msg.setAlertTitle("MoonlightTestXiaoMiMsg");
        msg.setAlertContent("Moonlight测试测试测试测试");
        msg.setMsgId(UUID.randomUUID().toString());
        msg.setPayload("12313132131");

//        Map<String, String> extra = new HashMap<>(16);
//        extra.put("intent_uri", "intent:#Intent;launchFlags=0x4000000;component=域名/安卓Activity全类名;S.caseId=4127;i.intoType=1;end");
//        msg.setExtra(extra);

        Result result = XiaoMiClient.getInstance().sendMessageToRegId(msg, 3);
        System.out.println("xiao mi push result = " + result);
    }

}